/*****************************************************************
 MYD Engine v0.1

 File: myd_physics.cpp
 Created: 11/07/09
*****************************************************************/

#include "myd_physics.h"

using namespace myd;

//--------------------------------------------------------------------------------------
Physics::Physics(void)
{
}

Physics::~Physics(void)
{
}
//--------------------------------------------------------------------------------------

void Physics::checkCollision(void) const
{
	for (int i=0; i<collisionVector.size()-1; i++)
		for (int j=i+1; j<collisionVector.size(); j++)
			boundingBox(collisionVector[i], collisionVector[j]);
}
//--------------------------------------------------------------------------------------
void Physics::kickOut(Entity *tm_entity, collisionType type, float penetration) const
{
	float newX, newY, Z;
	Z = tm_entity->getPosZ();

	if (type == up){
		newX = tm_entity->getPosX();
		newY = tm_entity->getPosY() + penetration;
		tm_entity->setPos(newX, newY, Z);
	}

	if (type == down){
		newX = tm_entity->getPosX();
		newY = tm_entity->getPosY() - penetration;
		tm_entity->setPos(newX, newY, Z);
	}
	
	if (type == left){
		newX = tm_entity->getPosX() - penetration;
		newY = tm_entity->getPosY();
		tm_entity->setPos(newX, newY, Z);
	}

	if (type == right){
		newX = tm_entity->getPosX() + penetration;
		newY = tm_entity->getPosY();
		tm_entity->setPos(newX, newY, Z);
	}
}

//--------------------------------------------------------------------------------------
void Physics::boundingBox(Entity *tm_ent1, Entity *tm_ent2) const
{
		float Xdistance = abs(tm_ent1->getPosX() - tm_ent2->getPosX());			
		float Ydistance = abs(tm_ent1->getPosY() - tm_ent2->getPosY());
		float Xradiuses = abs((tm_ent1->getWidth()/2) + (tm_ent2->getWidth()/2));
		float Yradiuses = abs((tm_ent1->getHeight()/2) + (tm_ent2->getHeight()/2));
		float Xpenetration = Xradiuses - Xdistance;
		float Ypenetration = Yradiuses - Ydistance;
		if (Xdistance < Xradiuses && Ydistance < Yradiuses){
			
			//entities' collides
			tm_ent1->onCollide(tm_ent2);
			tm_ent2->onCollide(tm_ent1);

			//classify penetrations
			if (Xpenetration > Ypenetration) //vertical
			{
			//do vertical kickout
			if (tm_ent1->isMoving)// i is moving
				if (tm_ent1->getPosY() > tm_ent2->getPosY())//up
					kickOut(tm_ent1, up, Ypenetration);
				else if (tm_ent1->getPosY() < tm_ent2->getPosY())//down
					kickOut(tm_ent1, down, Ypenetration);

			else //(default:) j is moving
				if (tm_ent2->getPosY() > tm_ent1->getPosY())//up
					kickOut(tm_ent2, up, Ypenetration);
				else if (tm_ent2->getPosY() < tm_ent1->getPosY())//down
					kickOut(tm_ent2, down, Ypenetration);
			}
			else //(default:) horizontal
			{ 
			//do horizontal kickout
			if (tm_ent1->isMoving)// i is moving
				if (tm_ent1->getPosX() > tm_ent2->getPosX())//right
					kickOut(tm_ent1, right, Xpenetration);
				else if (tm_ent1->getPosX() < tm_ent2->getPosX())//left
					kickOut(tm_ent1, left, Xpenetration);

			else //(default:) j is moving
				if (tm_ent2->getPosX() > tm_ent1->getPosX())//right
					kickOut(tm_ent2, right, Xpenetration);
				else if (tm_ent2->getPosX() < tm_ent1->getPosX())//left
					kickOut(tm_ent2, left, Xpenetration); }
		}
}
